package logic;

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Pattern;

import utils.Constant;
import utils.FileManager;

public class BuildLog {

	private FileManager fileManager = null;
	private static BuildLog buildLogger = null;

	private BuildLog() {
		fileManager = new FileManager();
	}

	public static BuildLog getInstance() {
		if (buildLogger == null) {
			buildLogger = new BuildLog();
		}
		return buildLogger;
	}

	public FileManager getFileManager() {
		return fileManager;
	}

	public List<String> getContent(List<String> contentTransformation) {
		List<String> outTransformation = new LinkedList<String>();
		Iterator<String> iterator = contentTransformation.iterator();
		String ruleName = "";
		while (iterator.hasNext()) {
			String auxLine = iterator.next();
			if (isTransformation(auxLine)) {
				outTransformation.add(Constant.IMPORT + Constant.CHANGE);
				outTransformation.add(Constant.ENDOFLINE);
				outTransformation.add(auxLine);

			} else if (isRuleSignature(auxLine)) {
				ruleName = getRuleName(auxLine);
				outTransformation.add(auxLine);
				outTransformation.add(Constant.TAB + Constant.IDDECLARATION);
				outTransformation.add(Constant.TAB + Constant.LOGGERSTARTRULE
						+ Constant.COMMAS + ruleName + Constant.COMMAS
						+ Constant.LOGGERENDLINE);

			} else if (isRuleEnd(auxLine)) {
				outTransformation.add(auxLine);
				outTransformation.add(Constant.TAB + Constant.LOGGERENDRULE
						+ Constant.COMMAS + ruleName + Constant.COMMAS
						+ Constant.LOGGERENDLINE);

				//ruleName = "";

			} else {
				outTransformation.add(auxLine);
			}
		}

		return outTransformation;
	}

	private boolean isRuleEnd(String codeLine) {
		return codeLine.replaceAll(" ", "").replaceAll("\t", "").contains(
				"result=")
				|| codeLine.replaceAll(" ", "").replaceAll("\t", "").contains(
						"result+=");
	}

	private String getRuleName(String ruleLine) {
		return ruleLine.replace("{", "");
	}

	private boolean isTransformation(String codeLine) {
		/*
		 * Put in pattern. String ttPattern = ".+texttransformation.+"; return
		 * Pattern.matches(ttPattern, codeLine);
		 */
		return codeLine.replace(" ", "").startsWith(Constant.TT);
	}

	private boolean isRuleSignature(String codeLine) {
		String rulePattern = ".+::.+\\(.*\\)(\\s)*(:.+)?";
		return Pattern.matches(rulePattern, codeLine);
	}

	public String formatContent(List<String> fileContent) {
		StringBuilder content = new StringBuilder();
		String space = Constant.SPACE;
		boolean end = false;
		for (int i = 0; i < fileContent.size(); i++) {
			if (fileContent.get(i).contains("START") && !end) {
				content.append(space + fileContent.get(i) + Constant.ENDOFLINE);
				space += Constant.SPACE;
			} else if (fileContent.get(i).contains("START") && end) {
				content.append(space + fileContent.get(i) + Constant.ENDOFLINE);
				end = true;
			} else if (fileContent.get(i).contains("END")) {
				space = space.replaceFirst(Constant.SPACE, "");
				content.append(space + fileContent.get(i) + Constant.ENDOFLINE);
				end = false;
			}
		}
		return content.toString();
	}

	public static void adjustmentLogger(String path) {
		BuildLog log = BuildLog.getInstance();
		File loggerFile = log.getFileManager().getLoggerPath(path, "txt");
		try {
			List<String> content = log.getFileManager().readTransformation(
					loggerFile);
			log.getFileManager().writeLogger(path, log.formatContent(content));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void generatorLogger(String path) {

		BuildLog log = BuildLog.getInstance();
		try {
			List<String> tts = log.getFileManager().getTransformations(path,
					"m2t");
			List<List<String>> ttsContent = new LinkedList<List<String>>();
			for (String tt : tts) {
				ttsContent.add(log.getContent(log.getFileManager()
						.readTransformation(new File(tt))));
			}
			for (int i = 0; i < ttsContent.size(); i++) {
				log.getFileManager().writeTransformation(
						ttsContent.get(i),
						tts.get(i)
								.replace(
										log.getFileManager().getCurrentRoot()
												.getName(),
										log.getFileManager().getCurrentRoot()
												.getName()
												+ Constant.INSTRUMENTED));
			}
			log.fileManager.createDir(log.fileManager.getCurrentRoot()
					.getAbsolutePath()
					+ Constant.INSTRUMENTED
					+ Constant.TABLET
					+ Constant.LOGGERROOT);
			List<String> logger = log.fileManager.readTransformation(new File(
					Constant.LOGGERROOT + Constant.LOGGER));
			for (int i = 0; i < logger.size(); i++) {
				if (logger.get(i).toString().contains(Constant.DELIMITER)) {
					String auxLine = logger.get(i)
							.replace(
									Constant.DELIMITER,
									log.fileManager.getCurrentRoot()
											.getAbsolutePath()
											+ Constant.INSTRUMENTED
											+ Constant.TABLET
											+ Constant.LOGGERROOT
											+ Constant.LOGGERNAME);
					logger.remove(i);
					logger.add(i, auxLine);
				}
			}
			log.fileManager.writeTransformation(logger, log.fileManager
					.getCurrentRoot().getAbsolutePath()
					+ Constant.INSTRUMENTED
					+ Constant.TABLET
					+ Constant.LOGGERROOT + Constant.LOGGER);

		} catch (IOException e) {
			e.printStackTrace();
		}

	}
}
